//go:build js || wasm

package godom

import "syscall/js"

// ElementWrapper
// https://developer.mozilla.org/ru/docs/Web/API/Element
type ElementWrapper interface {
	NodeWrapper

	AssignedSlot() string
	Attributes() js.Value
	ChildElementCount() int
	Children() HTMLCollectionWrapper
	ClassList() js.Value
	ClassName() string
	SetClassName(className string)
	ClientHeight() int
	ClientLeft() int
	ClientTop() int
	ClientWidth() int
	FirstElementChild() ElementWrapper
	Id() string
	SetId(id string)
	InnerHTML() string
	SetInnerHTML(innerHTML string)
	LastElementChild() ElementWrapper
	LocalName() string
	NamespaceURI() string
	NextElementSibling() ElementWrapper
	ScrollHeight() int
	ScrollLeft() int
	ScrollTop() int
	ScrollWidth() int
	//ShadowRoot() ShadowRoot
	Slot() string
	SetSlot(slot string)
	TagName() string

	After(nodes ...NodeWrapper)
	//Animate() []Element
	Append(nodes ...NodeWrapper)
	////AttachShadow() ShadowRoot
	Before(nodes ...NodeWrapper)
	//CheckVisibility() []Element
	Closest(selectors string) ElementWrapper
	//ComputedStyleMap() map[string]string
	//GetAnimations() []Element
	GetAttribute(attributeName string) string
	//GetAttributeNames() []string
	//GetAttributeNodes() []Element
	//GetAttributeNodesNS() []Element
	//GetAttributeNS(ns string) []Element
	////GetBoundingClientRect() Rect
	////GetClientRects() []Rect
	//GetElementByClassName(className string) Element
	//GetElementByTagName(className string) Element
	//GetElementByTagNameNS(ns string, localName string) Element
	//HasAttribute(name string) bool
	//HasAttributeNS(ns string) bool
	//HasAttributes(names ...string) bool
	//HasPointerCapture(pointerId int) bool
	//InsertAdjacentElement(position string, element Element) Element
	//InsertAdjacentHTML(position string, html string) Element
	//InsertAdjacentText(position string, text string) Element
	//Matches() []Element
	//Prepend() []Element
	//QuerySelector(selector string) Element
	//QuerySelectorAll(selector string) []Element
	//ReleasePointerCapture(pointerId int)
	//Remove() []Element
	//RemoveAttribute(name string)
	////RemoveAttributeNode(attr Attr)
	//RemoveAttributeNS(ns string)
	//ReplaceChildren() []Element
	//ReplaceWith() []Element
	//RequestFullscreen() Element
	//RequestPointerLock()
	//Scroll()
	//ScrollBy(x, y int)
	//ScrollIntoView()
	//ScrollTo()
	//SetAttribute(name string, value string)
	////SetAttributeNode(attr Attr)
	//SetAttributeNodeNS(ns string, localName string)
	//SetAttributeNS(ns string, name string, value string)
	//SetPointerCapture(pointerId int)
	//ToggleAttribute(name string)
}

type Element struct {
	Node
}

func (e *Element) JSValue() js.Value {
	return e.jsValue
}

func (e *Element) AssignedSlot() string {
	return e.jsValue.Get("assignedSlot").String()
}

func (e *Element) Attributes() js.Value {
	return e.jsValue.Get("attributes")
}

func (e *Element) ChildElementCount() int {
	return e.jsValue.Get("childElementCount").Int()
}

func (e *Element) Children() HTMLCollectionWrapper {
	return &HTMLCollection{e.jsValue.Get("children")}
}

func (e *Element) ClassList() js.Value {
	return e.jsValue.Get("classList")
}

func (e *Element) ClassName() string {
	return e.jsValue.Get("className").String()
}

func (e *Element) SetClassName(className string) {
	e.jsValue.Set("className", className)
}

func (e *Element) ClientHeight() int {
	return e.jsValue.Get("clientHeight").Int()
}

func (e *Element) ClientLeft() int {
	return e.jsValue.Get("clientLeft").Int()
}

func (e *Element) ClientTop() int {
	return e.jsValue.Get("clientTop").Int()
}

func (e *Element) ClientWidth() int {
	return e.jsValue.Get("clientWidth").Int()
}

func (e *Element) FirstElementChild() ElementWrapper {
	return &Element{Node{e.jsValue.Get("firstElementChild")}}
}

func (e *Element) Id() string {
	return e.jsValue.Get("id").String()
}

func (e *Element) SetId(id string) {
	e.jsValue.Set("id", id)
}

func (e *Element) InnerHTML() string {
	return e.jsValue.Get("innerHTML").String()
}

func (e *Element) SetInnerHTML(innerHTML string) {
	e.jsValue.Set("innerHTML", innerHTML)
}

func (e *Element) LastElementChild() ElementWrapper {
	return &Element{Node{e.jsValue.Get("lastElementChild")}}
}

func (e *Element) LocalName() string {
	return e.jsValue.Get("localName").String()
}

func (e *Element) NamespaceURI() string {
	return e.jsValue.Get("namespaceURI").String()
}

func (e *Element) NextElementSibling() ElementWrapper {
	return &Element{Node{e.jsValue.Get("nextElementSibling")}}
}

func (e *Element) ScrollHeight() int {
	return e.jsValue.Get("scrollHeight").Int()
}

func (e *Element) ScrollLeft() int {
	return e.jsValue.Get("scrollLeft").Int()
}

func (e *Element) ScrollTop() int {
	return e.jsValue.Get("scrollTop").Int()
}

func (e *Element) ScrollWidth() int {
	return e.jsValue.Get("scrollWidth").Int()
}

func (e *Element) Slot() string {
	return e.jsValue.Get("slot").String()
}

func (e *Element) SetSlot(slot string) {
	e.jsValue.Set("slot", slot)
}

func (e *Element) TagName() string {
	return e.jsValue.Get("tagName").String()
}

func (e *Element) After(nodes ...NodeWrapper) {
	for _, node := range nodes {
		e.jsValue.Call("after", node.JSValue())
	}
}

func (e *Element) Append(nodes ...NodeWrapper) {
	for _, node := range nodes {
		e.jsValue.Call("append", node.JSValue())
	}
}

func (e *Element) Before(nodes ...NodeWrapper) {
	for _, node := range nodes {
		e.jsValue.Call("before", node.JSValue())
	}
}

func (e *Element) Closest(selectors string) ElementWrapper {
	return &Element{Node{e.jsValue.Call("closest", selectors)}}
}

func (e *Element) GetAttribute(attributeName string) string {
	return e.jsValue.Call("getAttribute", attributeName).String()
}
